﻿using System;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
using UnityEngine.Networking;

namespace GxFramework
{
    public class AssetBundleInfo :IAssetInfo
    {

#region Asset请求
        object _assetRequests;
        AbAssetRequest GetAbRequest(string assetName, Type assetType, bool autoCreate)
        {
            AbAssetRequest ret = null;

            AbAssetRequest first = null;
            List<AbAssetRequest> list = null;
            if (_assetRequests is AbAssetRequest)
            {
                first = _assetRequests as AbAssetRequest;
                if (first.IsMatch(assetName, assetType))
                    return first;
            }
            else if (_assetRequests is List<AbAssetRequest>)
            {
                list = _assetRequests as List<AbAssetRequest>;
                var len = list.Count;
                for (int i = 0; i < len; ++i)
                {
                    ret = list[i];
                    if (ret.IsMatch(assetName, assetType))
                        return ret;
                }
            }
            ret = null;
            if (autoCreate)
            {
                ret = new AbAssetRequest();
                ret.Init(this, assetName, assetType);
                if (null == _assetRequests)
                    _assetRequests = ret;
                else
                {
                    if (null != first)
                    {
                        _assetRequests = list = new List<AbAssetRequest>();
                        list.Add(first);
                    }
                    list.Add(ret);
                }
            }
            return ret;
        }
        public AbAssetRequest AddListener(string assetName, Type assetType, AssetDelegate del)
        {
            var assetReq = GetAbRequest(assetName, assetType, true);
            assetReq.AddListener(del);
            return assetReq;
        }
        public void RemoveListener(string assetName, Type assetType, AssetDelegate del)
        {
            var assetReq = GetAbRequest(assetName, assetType, false);
            if (null != assetReq)
                assetReq.RemoveListener(del);
        }
        public int assetRequestCount
        {
            get 
            {
                if (null == _assetRequests)
                    return 0;
                if (_assetRequests is AbAssetRequest)
                    return 1;
                return (_assetRequests as List<AbAssetRequest>).Count;
            }
        }
        public void ClearAssetRequests()
        {
            _assetRequests = null;
        }
#endregion


        UnityWebRequest _request;
        AssetBundleRequest _allAssetsRequest;
        public string path { get; set; }
        public int refCount { get; private set; }
        public AssetBundle assetBundle { get; private set; }
        public Object[] allAssets { get; private set; }
        public int status { get; private set; }
        bool _preloadAllAssets;
        public bool preloadAllAssets
        {
            get{ return _preloadAllAssets;}
            set
            {
                if (this.isDone && _preloadAllAssets && null == this.allAssets && null != this.assetBundle)
                {
                    this.allAssets = this.assetBundle.LoadAllAssets();
                }
                _preloadAllAssets = value;
            }
        }
        public bool isDone { get { return status == AssetLoadStatus.Success || status == AssetLoadStatus.Fail; } }
        public string error { get; private set; }
        public float progress
        {
            get
            {
                if (this.isDone)
                    return 1f;
                var v = this.preloadAllAssets ? 0.8f:1f;
                if (null != _request)
                    return  v * _request.downloadProgress;
                return 0f;
            }
        }

        //在请求队列中：等待处理
        public void Wait()
        {
            this.status = AssetLoadStatus.Wait;
        }
        static string baseURL = null;
        //加载自身文件
        public void Load()
        {
            this.status = AssetLoadStatus.Running;
            if (null == baseURL)
            {
                baseURL = "file://" + Application.dataPath.Replace("Assets", "AssetBundles/android/");
            }
            _request = UnityWebRequest.GetAssetBundle(baseURL+path);
            _request.Send();
        }
        public void Update(AssetBundleLoader loader,AssetBundleAssetLoader loader2)
        {
            if (this.isDone)
                return;
            if (null != _request && _request.isDone && loader.IsDependencyDone(this))
            {
                this.error = _request.error;
                if (null == this.error)
                {
                    this.assetBundle = DownloadHandlerAssetBundle.GetContent(_request);
                    if(preloadAllAssets)
                        _allAssetsRequest = this.assetBundle.LoadAllAssetsAsync();
                }
                _request = null;
            }
            if (null != _allAssetsRequest && _allAssetsRequest.isDone)
            {
                this.allAssets = _allAssetsRequest.allAssets;
                _allAssetsRequest = null;
            }
            if (null == _request && null == _allAssetsRequest)
            {
                this.status = null == this.error ? AssetLoadStatus.Success : AssetLoadStatus.Fail;
                //InvokeListeners();
                this.Invoke(loader2);
            }
        }
        public void LoadAllAssets()
        {
            if (null == this.allAssets && null != this.assetBundle)
            {
                this.allAssets = this.assetBundle.LoadAllAssets();
            }
            
        }
        void InvokeListeners()
        {
            var assetRequests = this._assetRequests;
            if (null == assetRequests)
                return;
            if (assetRequests is AbAssetRequest)
            {
                (assetRequests as AbAssetRequest).Invoke();
            }
            else
            {
                var list = assetRequests as List<AbAssetRequest>;
                for (int i = 0; i < list.Count; ++i)
                    list[i].Invoke();
            }

        }
        void Invoke(AssetBundleAssetLoader loader)
        {
            var assetRequests = this._assetRequests;
            if (null == assetRequests)
                return;
            this._allAssetsRequest = null;
            if (assetRequests is AbAssetRequest)
            {
                loader.Load((assetRequests as AbAssetRequest));
                return;
            }
            var list = assetRequests as List<AbAssetRequest>;
            for (int i = 0; i < list.Count; ++i)
                loader.Load(list[i]);

        }
    }
}